home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 1997 May & June / Amiga-CD 1997 #5-6.iso / emulatoren / frodov2.4 / src / 6526.asm < prev    next >
Assembly Source File  |  1997-01-03  |  29KB  |  1,532 lines

  1. *
  2. * 6526.asm - CIA-Emulation
  3. *
  4. * Copyright (C) 1994-1996 by Christian Bauer
  5. *
  6.  
  7. *
  8. * Anmerkungen:
  9. * ------------
  10. *
  11. * Funktionsweise/Periodic:
  12. *  - Für jede (simulierte) C64-Rasterzeile wird vom 6510-Task die Routine
  13. *    Periodic6526 aufgerufen, die die Timer herunterzählt und ggf.
  14. *    Interrupts auslöst
  15. *
  16. * Timer/Latches:
  17. *  - Die Bytefolge im Register-File ist gegenüber dem echten 6526 umgekehrt,
  18. *    das wird aber bei den WriteTo6526- und ReadFrom6526-Routinen wieder
  19. *    ausgeglichen
  20. *
  21. * TOD-Clocks:
  22. *  - Die TODs werden synchron mit dem VBlank gezählt. Es wird also ein
  23. *    50Hz-Eingangssignal simuliert.
  24. *
  25. * Tastaturabfrage:
  26. *  - Das Feld KeyMatrix enthält für jede Taste entsprechend der C64-
  27. *    Tastaturmatrix ein Bit (0: Taste gedrückt, 1: Taste nicht gedrückt).
  28. *    InvKeyMatrix ist dieselbe Matrix mit vertauschten Zeilen und Spalten
  29. *    (für "inverse" Tastaturabfragen).
  30. *  - Bei Lesezugriffen aus CIA-A, Port A/B werden entsprechend der aktiven
  31. *    (ausgewählten) Zeilen der Tastatur die entsprechenden Bits aus der
  32. *    Tastaturmatrix zusammengestellt
  33. *  - F9 löst einen NMI aus (Restore), F10 einen RESET
  34. *
  35. * Joystickabfrage:
  36. *  - Die Joysticks werden im VBlank abgefragt, wenn auch die TODs
  37. *    gezählt werden
  38. *
  39. * Lightpen:
  40. *  - Bei jedem Schreibzugriff auf PRB/DDRB von CIA-A wird geprüft, ob die
  41. *    Lightpen-Leitung (Bit 4) einen Übergang 1->0 macht. In diesem Fall
  42. *    wird der VIC informiert.
  43. *
  44. * Inkompatibilitäten:
  45. *  - Die TOD-Clock sollte bei einem Lesezugriff nicht angehalten,
  46. *    sondern gelatcht werden
  47. *  - Der SDR-Interrupt ist nicht echt
  48. *
  49.  
  50.         MACHINE    68020
  51.  
  52.         XREF    ShowPrefs    ;Main.asm
  53.  
  54.         XREF    _ciaaprb
  55.         XREF    _ciaaddrb
  56.  
  57.         XREF    IntIsNMI    ;6510.asm
  58.         XREF    IntIsCIAIRQ
  59.         XREF    NMIState
  60.         XREF    Peri6526Cont
  61.  
  62.         XREF    ChangedVA    ;6569.asm
  63.         XREF    TriggerLightpen
  64.  
  65.         XREF    IECIsOpen    ;IEC.asm
  66.  
  67.         XDEF    Reset6526
  68.         XDEF    _GetCIA1Dump
  69.         XDEF    _GetCIA2Dump
  70.         XDEF    ReadFrom6526A
  71.         XDEF    ReadFrom6526B
  72.         XDEF    WriteTo6526A
  73.         XDEF    WriteTo6526B
  74.         XDEF    Periodic6526
  75.         XDEF    ChangedKeys
  76.         XDEF    CountTODs
  77.         XDEF    _KeyPressed
  78.  
  79.         XDEF    CIACycles    ;Prefs
  80.         XDEF    Joystick1On
  81.         XDEF    Joystick2On
  82.         XDEF    JoystickSwap
  83.         XDEF    KeyboardYZ
  84.  
  85.         SECTION    "text",CODE
  86.  
  87.  
  88. **
  89. ** Definitionen
  90. **
  91.  
  92. ; CIA-Register
  93. PRA        = 0
  94. PRB        = 1
  95. DDRA        = 2
  96. DDRB        = 3
  97. TAHI        = 4    ;Timer-Wert A
  98. TALO        = 5    ;Achtung: Umgekehrte Bytefolge!
  99. TBHI        = 6    ;Timer-Wert B
  100. TBLO        = 7
  101. TOD10THS    = 8
  102. TODSEC        = 9
  103. TODMIN        = 10
  104. TODHR        = 11
  105. SDR        = 12
  106. ICR        = 13    ;Interrupt-Data
  107. CRA        = 14
  108. CRB        = 15
  109.  
  110. ; Zusätzliche Register
  111. LTCHA        = 16    ;Timer-Latch A
  112. LTCHB        = 18    ;Timer-Latch B
  113. INTMASK        = 20    ;Interrupt-Enable
  114. TODHALT        = 21    ;TOD zwecks Beschreiben/Auslesen gestoppt
  115. ALM10THS    = 22    ;Alarmzeit
  116. ALMSEC        = 23
  117. ALMMIN        = 24
  118. ALMHR        = 25
  119. TODDIV        = 26    ;TOD-Frequenzteiler
  120. TACNTPHI2    = 27    ;Timer A läuft und zählt Phi2
  121. TBCNTPHI2    = 28    ;Timer B läuft und zählt Phi2
  122. TBCNTTA        = 29    ;Timer B läuft und zählt Unterläufe von Timer A
  123. PREVLP        = 30    ;Voriger Zustand der Lightpen-Leitung (nur CIA-A)
  124.  
  125. RPC        EQUR    a6    ;PC (32-Bit Amiga-Adresse, untere 16 Bit
  126.                 ;    stimmen mit C64-PC überein)
  127.  
  128.  
  129. **
  130. ** CIAs zurücksetzen
  131. **
  132.  
  133. ; CIA-A
  134. Reset6526    lea    Registers1,a0
  135.         clr.l    (a0)
  136.         clr.l    4(a0)
  137.         clr.l    8(a0)
  138.         clr.l    12(a0)
  139.         move.w    #-1,TAHI(a0)        ;Timer auf -1
  140.         move.w    #-1,TBHI(a0)
  141.  
  142.         move.w    #$0001,LTCHA(a0)    ;Latches auf 1
  143.         move.w    #$0001,LTCHB(a0)
  144.         clr.b    INTMASK(a0)        ;Interrupts abschalten
  145.         clr.b    TODHALT(a0)        ;TOD läuft
  146.         clr.l    ALM10THS(a0)        ;Alarmzeit auf 00:00:00.0
  147.         clr.w    TACNTPHI2(a0)        ;Beide Timer anhalten
  148.         clr.b    TBCNTTA(a0)
  149.         move.b    #$10,PREVLP(a0)        ;Lightpen-Leitung ist High
  150.  
  151.         move.b    #$ff,Joystick1        ;Joystick inaktiv
  152.         move.b    #$ff,Joystick2
  153.         move.b    #$ff,Joystick2Key
  154.  
  155. ; CIA-B
  156.         lea    Registers2,a0
  157.         clr.l    (a0)
  158.         clr.l    4(a0)
  159.         clr.l    8(a0)
  160.         clr.l    12(a0)
  161.         move.w    #-1,TAHI(a0)        ;Timer auf -1
  162.         move.w    #-1,TBHI(a0)
  163.  
  164.         move.w    #$0001,LTCHA(a0)    ;Latches auf 1
  165.         move.w    #$0001,LTCHB(a0)
  166.         clr.b    INTMASK(a0)        ;Interrupts abschalten
  167.         clr.b    TODHALT(a0)        ;TOD läuft
  168.         clr.l    ALM10THS(a0)        ;Alarmzeit auf 00:00:00.0
  169.         clr.w    TACNTPHI2(a0)        ;Beide Timer anhalten
  170.         clr.b    TBCNTTA(a0)
  171.  
  172. ; Tastaturmatrix löschen
  173.         moveq    #-1,d0
  174.         move.l    d0,KeyMatrix
  175.         move.l    d0,KeyMatrix+4
  176.         move.l    d0,InvKeyMatrix
  177.         move.l    d0,InvKeyMatrix+4
  178.  
  179. ; VIC-Bank 0 einstellen
  180.         moveq    #0,d0
  181.         bra    ChangedVA
  182.  
  183.  
  184. **
  185. ** CIA-Status in Datenstruktur schreiben
  186. **
  187.  
  188. _GetCIA1Dump    lea    Registers1,a0
  189.         bra    GetCIADump
  190.  
  191. _GetCIA2Dump    lea    Registers2,a0
  192.  
  193. GetCIADump    move.l    4(sp),a1
  194.         move.l    (a0),(a1)+
  195.         move.b    TALO(a0),(a1)+    ;Wegen umgekehrter Bytefolge
  196.         move.b    TAHI(a0),(a1)+
  197.         move.b    TBLO(a0),(a1)+
  198.         move.b    TBHI(a0),(a1)+
  199.         move.l    TOD10THS(a0),(a1)+
  200.         move.l    SDR(a0),(a1)+
  201.  
  202.         move.b    LTCHA+1(a0),(a1)+
  203.         move.b    LTCHA(a0),(a1)+
  204.         move.b    LTCHB+1(a0),(a1)+
  205.         move.b    LTCHB(a0),(a1)+
  206.         move.l    ALM10THS(a0),(a1)+
  207.         move.b    INTMASK(a0),(a1)
  208.         rts
  209.  
  210.  
  211. **
  212. ** Tastaturbelegung geändert, Y und Z sortieren
  213. **
  214.  
  215. ChangedKeys    tst.w    KeyboardYZ
  216.         bne    1$
  217.         move.l    #$00010004,KeyPatch1
  218.         move.l    #$00030001,KeyPatch2
  219.         rts
  220. 1$        move.l    #$00030001,KeyPatch1
  221.         move.l    #$00010004,KeyPatch2
  222.         rts
  223.  
  224.  
  225. **
  226. ** In ein CIA-A-Register schreiben
  227. ** d0.w: Registernummer ($00-$0f)
  228. ** d1.b: Byte
  229. **
  230. ** Darf das obere Wort von d0 und d1 nicht verändern!
  231. **
  232.  
  233. WriteTo6526A    lea    Registers1,a0
  234.         move.l    WriteTabA(pc,d0.w*4),a1
  235.         jmp    (a1)
  236.  
  237.         CNOP    0,4
  238. WriteTabA    dc.l    WrNormal
  239.         dc.l    WrAPRB
  240.         dc.l    WrNormal
  241.         dc.l    WrADDRB
  242.         dc.l    WrTALO
  243.         dc.l    WrTAHI
  244.         dc.l    WrTBLO
  245.         dc.l    WrTBHI
  246.         dc.l    WrTOD10THS
  247.         dc.l    WrTODSEC
  248.         dc.l    WrTODMIN
  249.         dc.l    WrTODHR
  250.         dc.l    WrASDR
  251.         dc.l    WrAICR
  252.         dc.l    WrCRA
  253.         dc.l    WrCRB
  254.  
  255. WrNormal    move.b    d1,(a0,d0.w)
  256.         rts
  257.  
  258. WrAPRB        move.b    d1,PRB(a0)
  259.         bra    CheckLP
  260.  
  261. WrADDRB        move.b    d1,DDRB(a0)
  262.  
  263. CheckLP        move.b    DDRB(a0),d0    ;Lightpen-Leitung
  264.         not.b    d0
  265.         or.b    PRB(a0),d0
  266.         and.b    #$10,d0
  267.         cmp.b    PREVLP(a0),d0    ;Änderung?
  268.         beq    1$
  269.         move.b    d0,PREVLP(a0)    ;Ja, negative Flanke?
  270.         bne    1$
  271.         bra    TriggerLightpen    ;Ja, LP triggern
  272. 1$        rts
  273.  
  274. WrTALO        move.b    d1,LTCHA+1(a0)
  275.         rts
  276.  
  277. WrTAHI        move.b    d1,LTCHA(a0)
  278.         btst    #0,CRA(a0)        ;Timer A gestoppt?
  279.         bne    1$
  280.         move.w    LTCHA(a0),TAHI(a0)    ;Ja, Timer laden
  281. 1$        rts
  282.  
  283. WrTBLO        move.b    d1,LTCHB+1(a0)
  284.         rts
  285.  
  286. WrTBHI        move.b    d1,LTCHB(a0)
  287.         btst    #0,CRB(a0)        ;Timer B gestoppt?
  288.         bne    1$
  289.         move.w    LTCHB(a0),TBHI(a0)    ;Ja, Timer laden
  290. 1$        rts
  291.  
  292. WrTOD10THS    and.b    #$0f,d1
  293.         clr.b    TODHALT(a0)        ;TOD weiterlaufen lassen
  294.         btst    #7,CRB(a0)        ;Alarm-Zeit schreiben?
  295.         bne    1$
  296.         move.b    d1,TOD10THS(a0)
  297.         rts
  298. 1$        move.b    d1,ALM10THS(a0)
  299.         rts
  300.  
  301. WrTODSEC    and.b    #$7f,d1
  302.         btst    #7,CRB(a0)        ;Alarm-Zeit schreiben?
  303.         bne    1$
  304.         move.b    d1,TODSEC(a0)
  305.         rts
  306. 1$        move.b    d1,ALMSEC(a0)
  307.         rts
  308.  
  309. WrTODMIN    and.b    #$7f,d1
  310.         btst    #7,CRB(a0)        ;Alarm-Zeit schreiben?
  311.         bne    1$
  312.         move.b    d1,TODMIN(a0)
  313.         rts
  314. 1$        move.b    d1,ALMMIN(a0)
  315.         rts
  316.  
  317. WrTODHR        and.b    #$9f,d1
  318.         st.b    TODHALT(a0)        ;TOD anhalten
  319.         btst    #7,CRB(a0)        ;Alarm-Zeit schreiben?
  320.         bne    1$
  321.         move.b    d1,TODHR(a0)
  322.         rts
  323. 1$        move.b    d1,ALMHR(a0)
  324.         rts
  325.  
  326. WrASDR        move.b    d1,SDR(a0)
  327.         or.b    #$08,ICR(a0)        ;SDR-Interrupt auslösen
  328.         btst    #3,INTMASK(a0)
  329.         beq    1$
  330.         or.b    #$80,ICR(a0)
  331.         st.b    IntIsCIAIRQ
  332. 1$        rts
  333.  
  334. WrAICR        move.b    -3(RPC),d0        ;Opcode lesen
  335.         cmp.b    #$9d,d0            ;STA Abs,X
  336.         beq    11$
  337.         cmp.b    #$99,d0            ;STA Abs,Y
  338.         bne    10$
  339. 11$        clr.b    ICR(a0)            ;IRQ bei indizierter Adressierung löschen
  340.         clr.b    IntIsCIAIRQ
  341.  
  342. 10$        bclr    #7,d1            ;S/C-Bit löschen
  343.         bne    1$            ;War es gesetzt?
  344.         not.b    d1            ;Nein, Bits zum Löschen negieren
  345.         and.b    d1,INTMASK(a0)        ;Und Bits löschen
  346.         bra    2$
  347. 1$        or.b    d1,INTMASK(a0)        ;Bits setzen
  348. 2$
  349.         move.b    ICR(a0),d0        ;Anstehende Interrupts erlaubt?
  350.         and.b    INTMASK(a0),d0
  351.         and.b    #$1f,d0
  352.         beq    3$
  353.         or.b    #$80,ICR(a0)        ;Ja, IRQ auslösen
  354.         st.b    IntIsCIAIRQ
  355. 3$        rts                ;Nein
  356.  
  357. WrCRA        bclr    #4,d1            ;Force load?
  358.         beq    1$
  359.         move.w    LTCHA(a0),TAHI(a0)    ;Ja, Timer laden
  360. 1$        move.b    d1,CRA(a0)
  361.  
  362.         and.b    #$21,d1            ;Läuft der Timer und zählt er Phi2?
  363.         cmp.b    #$01,d1
  364.         seq.b    TACNTPHI2(a0)        ;Ja, Flag setzen
  365.         rts
  366.  
  367. WrCRB        bclr    #4,d1            ;Force load?
  368.         beq    1$
  369.         move.w    LTCHB(a0),TBHI(a0)    ;Ja, Timer laden
  370. 1$        move.b    d1,CRB(a0)
  371.  
  372.         and.b    #$61,d1            ;Läuft der Timer und zählt er Phi2?
  373.         cmp.b    #$01,d1
  374.         seq.b    TBCNTPHI2(a0)        ;Ja, Flag setzen
  375.         cmp.b    #$41,d1            ;Läuft er und zählt Unterläuft von Timer A?
  376.         seq.b    TBCNTTA(a0)        ;Ja, Flag setzen
  377.         rts
  378.  
  379.  
  380. **
  381. ** In ein CIA-B-Register schreiben
  382. ** d0.w: Registernummer ($00-$0f)
  383. ** d1.b: Byte
  384. **
  385. ** Darf das obere Wort von d0 und d1 nicht verändern!
  386. **
  387.  
  388. WriteTo6526B    lea    Registers2,a0
  389.         move.l    WriteTabB(pc,d0.w*4),a1
  390.         jmp    (a1)
  391.  
  392.         CNOP    0,4
  393. WriteTabB    dc.l    WrBPRA
  394.         dc.l    WrNormal
  395.         dc.l    WrBDDRA
  396.         dc.l    WrNormal
  397.         dc.l    WrTALO
  398.         dc.l    WrTAHI
  399.         dc.l    WrTBLO
  400.         dc.l    WrTBHI
  401.         dc.l    WrTOD10THS
  402.         dc.l    WrTODSEC
  403.         dc.l    WrTODMIN
  404.         dc.l    WrTODHR
  405.         dc.l    WrBSDR
  406.         dc.l    WrBICR
  407.         dc.l    WrCRA
  408.         dc.l    WrCRB
  409.  
  410. WrBPRA        move.b    d1,PRA(a0)        ;Floppy/VA
  411.         tst.b    IECIsOpen        ;Wenn IEC aktiv ist, Port setzen
  412.         beq    WrBNewVA
  413.         move.b    d1,_ciaaprb
  414.         bra    WrBNewVA
  415.  
  416. WrBDDRA        move.b    d1,DDRA(a0)        ;Floppy/VA
  417.         tst.b    IECIsOpen        ;Wenn IEC aktiv ist, DDR setzen
  418.         beq    WrBNewVA
  419.         move.b    d1,_ciaaddrb
  420. WrBNewVA    move.b    DDRA(a0),d0        ;VA extrahieren
  421.         not.b    d0
  422.         or.b    PRA(a0),d0
  423.         not.b    d0
  424.         and.b    #$03,d0
  425.         bra    ChangedVA        ;Und dem VIC mitteilen
  426.  
  427. WrBSDR        move.b    d1,SDR(a0)
  428.         or.b    #$08,ICR(a0)        ;SDR-Interrupt auslösen
  429.         btst    #3,INTMASK(a0)
  430.         beq    1$
  431.         or.b    #$80,ICR(a0)
  432.         tst.b    NMIState
  433.         bne    1$
  434.         st.b    NMIState
  435.         st.b    IntIsNMI
  436. 1$        rts
  437.  
  438. WrBICR        move.b    -3(RPC),d0        ;Opcode lesen
  439.         cmp.b    #$9d,d0            ;STA Abs,X
  440.         beq    11$
  441.         cmp.b    #$99,d0            ;STA Abs,Y
  442.         bne    10$
  443. 11$        clr.b    ICR(a0)            ;IRQ bei indizierter Adressierung löschen
  444.         clr.b    NMIState
  445.  
  446. 10$        bclr    #7,d1            ;S/C-Bit löschen
  447.         bne    1$            ;War es gesetzt?
  448.         not.b    d1            ;Nein, Bits zum Löschen negieren
  449.         and.b    d1,INTMASK(a0)        ;Und Bits löschen
  450.         bra    2$
  451. 1$        or.b    d1,INTMASK(a0)        ;Bits setzen
  452. 2$
  453.         move.b    ICR(a0),d0        ;Anstehende Interrupts erlaubt?
  454.         and.b    INTMASK(a0),d0
  455.         and.b    #$1f,d0
  456.         beq    3$
  457.         or.b    #$80,ICR(a0)        ;Ja, NMI auslösen
  458.         tst.b    NMIState
  459.         bne    3$
  460.         st.b    NMIState
  461.         st.b    IntIsNMI
  462. 3$        rts                ;Nein
  463.  
  464.  
  465. **
  466. ** Aus einem CIA-A-Register lesen
  467. ** d0.w: Registernummer ($00-$0f)
  468. ** Rückgabe: d0.b: Byte
  469. **
  470. ** Darf das obere Wort von d0 und d1 nicht verändern!
  471. **
  472.  
  473. ReadFrom6526A    lea    Registers1,a0
  474.         move.l    ReadTabA(pc,d0.w*4),a1
  475.         jmp    (a1)
  476.  
  477.         CNOP    0,4
  478. ReadTabA    dc.l    RdAPRA
  479.         dc.l    RdAPRB
  480.         dc.l    RdANormal
  481.         dc.l    RdANormal
  482.         dc.l    RdATALO
  483.         dc.l    RdATAHI
  484.         dc.l    RdATBLO
  485.         dc.l    RdATBHI
  486.         dc.l    RdATOD10THS
  487.         dc.l    RdANormal
  488.         dc.l    RdANormal
  489.         dc.l    RdATODHR
  490.         dc.l    RdANormal
  491.         dc.l    RdAICR
  492.         dc.l    RdANormal
  493.         dc.l    RdANormal
  494.  
  495. RdANormal    move.b    (a0,d0.w),d0
  496.         rts
  497.  
  498. RdAPRA        lea    InvKeyMatrix,a1
  499.         move.b    DDRB(a0),d1    ;Tastaturabfrage
  500.         not.b    d1
  501.         or.b    PRB(a0),d1
  502.         and.b    Joystick1,d1
  503.         move.b    DDRA(a0),d0
  504.         not.b    d0
  505.         or.b    PRA(a0),d0
  506.  
  507.         lsr.b    #1,d1        ;Alle aktiven Spalten dazuANDen
  508.         bcs    1$
  509.         and.b    (a1),d0
  510. 1$        lsr.b    #1,d1
  511.         bcs    2$
  512.         and.b    1(a1),d0
  513. 2$        lsr.b    #1,d1
  514.         bcs    3$
  515.         and.b    2(a1),d0
  516. 3$        lsr.b    #1,d1
  517.         bcs    4$
  518.         and.b    3(a1),d0
  519. 4$        lsr.b    #1,d1
  520.         bcs    5$
  521.         and.b    4(a1),d0
  522. 5$        lsr.b    #1,d1
  523.         bcs    6$
  524.         and.b    5(a1),d0
  525. 6$        lsr.b    #1,d1
  526.         bcs    7$
  527.         and.b    6(a1),d0
  528. 7$        lsr.b    #1,d1
  529.         bcs    8$
  530.         and.b    7(a1),d0
  531. 8$
  532.         and.b    Joystick2,d0
  533.         rts
  534.  
  535. RdAPRB        lea    KeyMatrix,a1
  536.         move.b    DDRA(a0),d1    ;Tastaturabfrage
  537.         not.b    d1
  538.         or.b    PRA(a0),d1
  539.         and.b    Joystick2,d1
  540.         move.b    DDRB(a0),d0
  541.         not.b    d0
  542.  
  543.         lsr.b    #1,d1        ;Alle aktiven Reihen dazuANDen
  544.         bcs    1$
  545.         and.b    (a1),d0
  546. 1$        lsr.b    #1,d1
  547.         bcs    2$
  548.         and.b    1(a1),d0
  549. 2$        lsr.b    #1,d1
  550.         bcs    3$
  551.         and.b    2(a1),d0
  552. 3$        lsr.b    #1,d1
  553.         bcs    4$
  554.         and.b    3(a1),d0
  555. 4$        lsr.b    #1,d1
  556.         bcs    5$
  557.         and.b    4(a1),d0
  558. 5$        lsr.b    #1,d1
  559.         bcs    6$
  560.         and.b    5(a1),d0
  561. 6$        lsr.b    #1,d1
  562.         bcs    7$
  563.         and.b    6(a1),d0
  564. 7$        lsr.b    #1,d1
  565.         bcs    8$
  566.         and.b    7(a1),d0
  567. 8$
  568.         move.b    PRB(a0),d1
  569.         and.b    DDRB(a0),d1
  570.         or.b    d1,d0
  571.         and.b    Joystick1,d0
  572.         rts
  573.  
  574. RdATALO        move.b    TALO(a0),d0    ;Weil die Timer im Registerfile
  575.         rts            ;als big-endian gespeichert sind
  576.  
  577. RdATAHI        move.b    TAHI(a0),d0
  578.         rts
  579.  
  580. RdATBLO        move.b    TBLO(a0),d0
  581.         rts
  582.  
  583. RdATBHI        move.b    TBHI(a0),d0
  584.         rts
  585.  
  586. RdATOD10THS    move.b    TOD10THS(a0),d0
  587.         clr.b    TODHALT(a0)    ;TOD weiterlaufen lassen
  588.         rts
  589.  
  590. RdATODHR    st.b    TODHALT(a0)    ;TOD anhalten
  591.         move.b    TODHR(a0),d0
  592.         rts
  593.  
  594. RdAICR        move.b    ICR(a0),d0    ;ICR beim Lesen löschen
  595.         clr.b    ICR(a0)
  596.         clr.b    IntIsCIAIRQ    ;IRQ zurücknehmen
  597.         rts
  598.  
  599.  
  600. **
  601. ** Aus einem CIA-B-Register lesen
  602. ** d0.w: Registernummer ($00-$0f)
  603. ** Rückgabe: d0.b: Byte
  604. **
  605. ** Darf das obere Wort von d0 und d1 nicht verändern!
  606. **
  607.  
  608. ReadFrom6526B    lea    Registers2,a0
  609.         move.l    ReadTabB(pc,d0.w*4),a1
  610.         jmp    (a1)
  611.  
  612.         CNOP    0,4
  613. ReadTabB    dc.l    RdBPRA
  614.         dc.l    RdBPRB
  615.         dc.l    RdBNormal
  616.         dc.l    RdBNormal
  617.         dc.l    RdBTALO
  618.         dc.l    RdBTAHI
  619.         dc.l    RdBTBLO
  620.         dc.l    RdBTBHI
  621.         dc.l    RdBTOD10THS
  622.         dc.l    RdBNormal
  623.         dc.l    RdBNormal
  624.         dc.l    RdBTODHR
  625.         dc.l    RdBNormal
  626.         dc.l    RdBICR
  627.         dc.l    RdBNormal
  628.         dc.l    RdBNormal
  629.  
  630. RdBNormal    move.b    (a0,d0.w),d0
  631.         rts
  632.  
  633. RdBPRA        move.b    DDRA(a0),d0    ;Floppy/VA
  634.         not.b    d0
  635.         or.b    PRA(a0),d0
  636.  
  637.         tst.b    IECIsOpen    ;Wenn IEC aktiv ist, davon lesen
  638.         beq    1$
  639.         and.b    #$03,d0
  640.         move.b    _ciaaprb,d1
  641.         and.b    #$fc,d1
  642.         or.b    d1,d0
  643. 1$        rts
  644.  
  645. RdBPRB        move.b    DDRB(a0),d0    ;Userport
  646.         not.b    d0        ;Eingabebits immer 1
  647.         or.b    PRB(a0),d0
  648.         rts
  649.  
  650. RdBTALO        move.b    TALO(a0),d0    ;Weil die Timer im Registerfile
  651.         rts            ;als big-endian gespeichert sind
  652.  
  653. RdBTAHI        move.b    TAHI(a0),d0
  654.         rts
  655.  
  656. RdBTBLO        move.b    TBLO(a0),d0
  657.         rts
  658.  
  659. RdBTBHI        move.b    TBHI(a0),d0
  660.         rts
  661.  
  662. RdBTOD10THS    move.b    TOD10THS(a0),d0
  663.         clr.b    TODHALT(a0)    ;TOD weiterlaufen lassen
  664.         rts
  665.  
  666. RdBTODHR    st.b    TODHALT(a0)    ;TOD anhalten
  667.         move.b    TODHR(a0),d0
  668.         rts
  669.  
  670. RdBICR        move.b    ICR(a0),d0    ;ICR beim Lesen löschen
  671.         clr.b    ICR(a0)
  672.         clr.b    NMIState    ;NMI zurücknehmen
  673.         rts
  674.  
  675.  
  676. **
  677. ** Wird jede Rasterzeile einmal aufgerufen
  678. **
  679.  
  680. *
  681. * CIA-A
  682. * d1: ICR
  683. * d2: INTMASK
  684. * d3: CIACycles
  685. *
  686.  
  687. Periodic6526    lea    Registers1,a0
  688.         move.b    ICR(a0),d1
  689.         move.b    INTMASK(a0),d2
  690.         move.w    CIACycles,d3
  691.  
  692. *
  693. * Timer A
  694. *
  695.  
  696.         tst.b    TACNTPHI2(a0)    ;Wird Phi2 gezählt?
  697.         beq    CiaATADone
  698.  
  699.         sub.w    d3,TAHI(a0)    ;Ja, herabzählen
  700.         bcc    CiaATADone    ;Unterlauf?
  701.  
  702.         or.b    #$01,d1        ;Ja, IRQ-Bit setzen
  703.         btst    #0,d2        ;IRQ freigegeben?
  704.         beq    CiaATANoIRQ
  705.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  706.         st.b    IntIsCIAIRQ    ;und IRQ auslösen
  707.  
  708. CiaATANoIRQ    move.w    LTCHA(a0),TAHI(a0) ;Zähler neu laden
  709.         btst    #3,CRA(a0)    ;One-Shot?
  710.         beq    1$
  711.         and.b    #$fe,CRA(a0)    ;Ja, Zähler stoppen
  712.         clr.b    TACNTPHI2(a0)
  713.  
  714. 1$        tst.b    TBCNTTA(a0)    ;Läuft Timer B und zählt er
  715.         beq    CiaATADone    ; Unterläufe von Timer A?
  716.  
  717.         subq.w    #1,TBHI(a0)    ;Ja, Timer B runterzählen
  718.         bcs    CiaATBUnderflow    ;Untergelaufen?
  719. CiaATADone
  720.  
  721. *
  722. * Timer B
  723. *
  724.  
  725.         tst.b    TBCNTPHI2(a0)    ;Wird Phi2 gezählt?
  726.         beq    CiaATBDone
  727.  
  728.         sub.w    d3,TBHI(a0)    ;Ja, herabzählen
  729.         bcc    CiaATBDone    ;Unterlauf?
  730.  
  731. CiaATBUnderflow    or.b    #$02,d1        ;Ja, IRQ-Bit setzen
  732.         btst    #1,d2        ;IRQ freigegeben?
  733.         beq    CiaATBNoIRQ
  734.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  735.         st.b    IntIsCIAIRQ    ;und IRQ auslösen
  736.  
  737. CiaATBNoIRQ    move.w    LTCHB(a0),TBHI(a0) ;Zähler neu laden
  738.         btst    #3,CRB(a0)    ;One-Shot?
  739.         beq    CiaATBDone
  740.         and.b    #$fe,CRB(a0)    ;Ja, Zähler stoppen
  741.         clr.b    TBCNTPHI2(a0)
  742.         clr.b    TBCNTTA(a0)
  743. CiaATBDone
  744.  
  745. *
  746. * ICR zurückschreiben
  747. *
  748.  
  749.         move.b    d1,ICR(a0)
  750.  
  751. *
  752. * CIA-B
  753. * d1: ICR
  754. * d2: INTMASK
  755. * d3: CIACycles
  756. *
  757.  
  758.         lea    Registers2,a0
  759.         move.b    ICR(a0),d1
  760.         move.b    INTMASK(a0),d2
  761.  
  762. *
  763. * Timer A
  764. *
  765.  
  766.         tst.b    TACNTPHI2(a0)    ;Wird Phi2 gezählt?
  767.         beq    CiaBTADone
  768.  
  769.         sub.w    d3,TAHI(a0)    ;Ja, herabzählen
  770.         bcc    CiaBTADone    ;Unterlauf?
  771.  
  772.         or.b    #$01,d1        ;Ja, IRQ-Bit setzen
  773.         btst    #0,d2        ;IRQ freigegeben?
  774.         beq    CiaBTANoIRQ
  775.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  776.         tst.b    NMIState    ;NMI schon ausgelöst?
  777.         bne    1$
  778.         st.b    NMIState    ;Nein, NMI auslösen
  779.         st.b    IntIsNMI
  780. 1$
  781.  
  782. CiaBTANoIRQ    move.w    LTCHA(a0),TAHI(a0) ;Zähler neu laden
  783.         btst    #3,CRA(a0)    ;One-Shot?
  784.         beq    1$
  785.         and.b    #$fe,CRA(a0)    ;Ja, Zähler stoppen
  786.         clr.b    TACNTPHI2(a0)
  787.  
  788. 1$        tst.b    TBCNTTA(a0)    ;Läuft Timer B und zählt er
  789.         beq    CiaBTADone    ; Unterläufe von Timer A?
  790.  
  791.         subq.w    #1,TBHI(a0)    ;Ja, Timer B runterzählen
  792.         bcs    CiaBTBUnderflow    ;Untergelaufen?
  793. CiaBTADone
  794.  
  795. *
  796. * Timer B
  797. *
  798.  
  799.         tst.b    TBCNTPHI2(a0)    ;Wird Phi2 gezählt?
  800.         beq    CiaBTBDone
  801.  
  802.         sub.w    d3,TBHI(a0)    ;Ja, herabzählen
  803.         bcc    CiaBTBDone    ;Unterlauf?
  804.  
  805. CiaBTBUnderflow    or.b    #$02,d1        ;Ja, IRQ-Bit setzen
  806.         btst    #1,d2        ;IRQ freigegeben?
  807.         beq    CiaBTBNoIRQ
  808.         or.b    #$80,d1        ;Ja, IR-Bit setzen
  809.         tst.b    NMIState    ;NMI schon ausgelöst?
  810.         bne    1$
  811.         st.b    NMIState    ;Nein, NMI auslösen
  812.         st.b    IntIsNMI
  813. 1$
  814.  
  815. CiaBTBNoIRQ    move.w    LTCHB(a0),TBHI(a0) ;Zähler neu laden
  816.         btst    #3,CRB(a0)    ;One-Shot?
  817.         beq    CiaBTBDone
  818.         and.b    #$fe,CRB(a0)    ;Ja, Zähler stoppen
  819.         clr.b    TBCNTPHI2(a0)
  820.         clr.b    TBCNTTA(a0)
  821. CiaBTBDone
  822.  
  823. *
  824. * ICR zurückschreiben
  825. *
  826.  
  827.         move.b    d1,ICR(a0)
  828.  
  829. ; In 6510-Task zurückspringen
  830.         bra    Peri6526Cont
  831.  
  832.  
  833. **
  834. ** TODs zählen
  835. **
  836.  
  837. *
  838. * CIA-A
  839. *
  840.  
  841. CountTODs    lea    Registers1,a0
  842.         subq.b    #1,TODDIV(a0)    ;Frequenzteiler herabzählen
  843.         bpl    CiaATODNop
  844.  
  845.         btst    #7,CRA(a0)    ;Untergelaufen,
  846.         beq    CiaATOD60Hz    ; je nach 50/60Hz-Flag neu laden
  847.         move.b    #4,TODDIV(a0)
  848.         bra    CiaATODLoaded
  849. CiaATOD60Hz    move.b    #5,TODDIV(a0)
  850.  
  851. CiaATODLoaded    move    #0,ccr        ;X löschen
  852.         move.b    #1,d0        ;1/10 Sekunden erhöhen
  853.         move.b    TOD10THS(a0),d1
  854.         abcd    d0,d1
  855.         move.b    d1,TOD10THS(a0)
  856.         cmp.b    #$10,d1        ;Über 10?
  857.         blo    CiaATODDone
  858.  
  859.         clr.b    TOD10THS(a0)    ;Ja, 1/10 Sekunden auf Null setzen
  860.         move    #0,ccr        ;und Sekunden erhöhen
  861.         move.b    #1,d0
  862.         move.b    TODSEC(a0),d1
  863.         abcd    d0,d1
  864.         move.b    d1,TODSEC(a0)
  865.         cmp.b    #$60,d1        ;Über 60?
  866.         blo    CiaATODDone
  867.  
  868.         clr.b    TODSEC(a0)    ;Ja, Sekunden auf Null setzen
  869.         move    #0,ccr        ;und Minuten erhöhen
  870.         move.b    #1,d0
  871.         move.b    TODMIN(a0),d1
  872.         abcd    d0,d1
  873.         move.b    d1,TODMIN(a0)
  874.         cmp.b    #$60,d1        ;Über 60?
  875.         blo    CiaATODDone
  876.  
  877.         clr.b    TODMIN(a0)    ;Ja, Minuten auf Null setzen
  878.         move    #0,ccr        ;und Stunden erhöhen
  879.         move.b    #1,d0
  880.         move.b    TODHR(a0),d1
  881.         and.b    #$1f,d1        ;AM/PM ausmaskieren
  882.         abcd    d0,d1
  883.         and.b    #$80,TODHR(a0)    ;Stunden schreiben, AM/PM lassen
  884.         or.b    d1,TODHR(a0)
  885.  
  886.         cmp.b    #$12,d1        ;Über 12?
  887.         blo    CiaATODDone
  888.  
  889.         and.b    #$80,TODHR(a0)    ;Ja, Stunden auf Null setzen
  890.         eor.b    #$80,TODHR(a0)    ;und AM/PM umdrehen
  891.  
  892. CiaATODDone    move.l    TOD10THS(a0),d0    ;Alarmzeit erreicht?
  893.         cmp.l    ALM10THS(a0),d0
  894.         bne    CiaATODNop
  895.         move.b    ICR(a0),d0    ;Ja, IRQ-Bit setzen
  896.         or.b    #$04,d0
  897.         btst    #2,INTMASK(a0)    ;IRQ freigegeben?
  898.         beq    CiaATODNoIRQ
  899.         or.b    #$80,d0        ;Ja, IR-Bit setzen
  900.         st.b    IntIsCIAIRQ    ;und IRQ auslösen
  901. CiaATODNoIRQ    move.b    d0,ICR(a0)
  902. CiaATODNop
  903.  
  904. *
  905. * CIA-B
  906. *
  907.  
  908.         lea    Registers2,a0
  909.         subq.b    #1,TODDIV(a0)    ;Frequenzteiler herabzählen
  910.         bpl    CiaBTODNop
  911.  
  912.         btst    #7,CRA(a0)    ;Untergelaufen,
  913.         beq    CiaBTOD60Hz    ; je nach 50/60Hz-Flag neu laden
  914.         move.b    #4,TODDIV(a0)
  915.         bra    CiaBTODLoaded
  916. CiaBTOD60Hz    move.b    #5,TODDIV(a0)
  917.  
  918. CiaBTODLoaded    move    #0,ccr        ;X löschen
  919.         move.b    #1,d0        ;1/10 Sekunden erhöhen
  920.         move.b    TOD10THS(a0),d1
  921.         abcd    d0,d1
  922.         move.b    d1,TOD10THS(a0)
  923.         cmp.b    #$10,d1        ;Über 10?
  924.         blo    CiaBTODDone
  925.  
  926.         clr.b    TOD10THS(a0)    ;Ja, 1/10 Sekunden auf Null setzen
  927.         move    #0,ccr        ;und Sekunden erhöhen
  928.         move.b    #1,d0
  929.         move.b    TODSEC(a0),d1
  930.         abcd    d0,d1
  931.         move.b    d1,TODSEC(a0)
  932.         cmp.b    #$60,d1        ;Über 60?
  933.         blo    CiaBTODDone
  934.  
  935.         clr.b    TODSEC(a0)    ;Ja, Sekunden auf Null setzen
  936.         move    #0,ccr        ;und Minuten erhöhen
  937.         move.b    #1,d0
  938.         move.b    TODMIN(a0),d1
  939.         abcd    d0,d1
  940.         move.b    d1,TODMIN(a0)
  941.         cmp.b    #$60,d1        ;Über 60?
  942.         blo    CiaBTODDone
  943.  
  944.         clr.b    TODMIN(a0)    ;Ja, Minuten auf Null setzen
  945.         move    #0,ccr        ;und Stunden erhöhen
  946.         move.b    #1,d0
  947.         move.b    TODHR(a0),d1
  948.         and.b    #$1f,d1        ;AM/PM ausmaskieren
  949.         abcd    d0,d1
  950.         and.b    #$80,TODHR(a0)    ;Stunden schreiben, AM/PM lassen
  951.         or.b    d1,TODHR(a0)
  952.  
  953.         cmp.b    #$12,d1        ;Über 12?
  954.         blo    CiaBTODDone
  955.  
  956.         and.b    #$80,TODHR(a0)    ;Ja, Stunden auf Null setzen
  957.         eor.b    #$80,TODHR(a0)    ;und AM/PM umdrehen
  958.  
  959. CiaBTODDone    move.l    TOD10THS(a0),d0    ;Alarmzeit erreicht?
  960.         cmp.l    ALM10THS(a0),d0
  961.         bne    CiaBTODNop
  962.         move.b    ICR(a0),d0    ;Ja, IRQ-Bit setzen
  963.         or.b    #$04,d0
  964.         btst    #2,INTMASK(a0)    ;IRQ freigegeben?
  965.         beq    CiaBTODNoIRQ
  966.         or.b    #$80,d0        ;Ja, IR-Bit setzen
  967.         tst.b    NMIState    ;NMI schon ausgelöst?
  968.         bne    1$
  969.         st.b    NMIState    ;Nein, NMI auslösen
  970.         st.b    IntIsNMI
  971. 1$
  972. CiaBTODNoIRQ    move.b    d0,ICR(a0)
  973. CiaBTODNop
  974.  
  975. *
  976. * Joystickabfrage
  977. *
  978.  
  979.         lea    Registers1,a0
  980.  
  981. ; Port 1
  982.         move.b    #$ff,d2        ;Vorgabe: Joystick inaktiv
  983.         tst.w    Joystick1On(pc)
  984.         beq    15$
  985.  
  986.         btst    #6,$bfe001    ;Feuerknopf
  987.         bne    11$
  988.         bclr    #4,d2
  989.  
  990. 11$        move.w    $dff00a,d0
  991.         btst    #1,d0        ;Rechts
  992.         beq    12$
  993.         bclr    #3,d2
  994.  
  995. 12$        btst    #9,d0        ;Links
  996.         beq    13$
  997.         bclr    #2,d2
  998.  
  999. 13$        move.w    d0,d1
  1000.         add.w    d0,d0
  1001.         eor.w    d1,d0
  1002.         btst    #1,d0        ;Runter
  1003.         beq    14$
  1004.         bclr    #1,d2
  1005.  
  1006. 14$        btst    #9,d0        ;Hoch
  1007.         beq    15$
  1008.         bclr    #0,d2
  1009.  
  1010. 15$        move.b    d2,Joystick1
  1011.  
  1012. ; Port 2
  1013.         move.b    Joystick2Key,d2    ;Vorgabe: Zehnerblock-Emulation
  1014.         tst.w    Joystick2On(pc)
  1015.         beq    25$
  1016.  
  1017.         btst    #7,$bfe001    ;Feuerknopf
  1018.         bne    21$
  1019.         bclr    #4,d2
  1020.  
  1021. 21$        move.w    $dff00c,d0
  1022.         btst    #1,d0        ;Rechts
  1023.         beq    22$
  1024.         bclr    #3,d2
  1025.  
  1026. 22$        btst    #9,d0        ;Links
  1027.         beq    23$
  1028.         bclr    #2,d2
  1029.  
  1030. 23$        move.w    d0,d1
  1031.         add.w    d0,d0
  1032.         eor.w    d1,d0
  1033.         btst    #1,d0        ;Runter
  1034.         beq    24$
  1035.         bclr    #1,d2
  1036.  
  1037. 24$        btst    #9,d0        ;Hoch
  1038.         beq    25$
  1039.         bclr    #0,d2
  1040.  
  1041. 25$        move.b    d2,Joystick2
  1042.  
  1043. ; Joysticks vertauschen?
  1044.         tst.w    JoystickSwap(pc)
  1045.         beq    30$
  1046.         move.b    Joystick1,d0
  1047.         move.b    Joystick2,Joystick1
  1048.         move.b    d0,Joystick2
  1049. 30$        rts
  1050.  
  1051.  
  1052. **
  1053. ** Taste wurde gedrückt
  1054. **
  1055.  
  1056. KeyDown        MACRO
  1057.         bclr    #\1,\2(a0)
  1058.         bclr    #\2,\1(a1)
  1059.         ENDM
  1060.  
  1061. KeyUp        MACRO
  1062.         bset    #\1,\2(a0)
  1063.         bset    #\2,\1(a1)
  1064.         ENDM
  1065.  
  1066. _KeyPressed    move.l    4(sp),d0
  1067.         lea    KeyMatrix,a0
  1068.         lea    InvKeyMatrix,a1
  1069.  
  1070.         bclr    #7,d0                ;KeyUp/KeyDown
  1071.         bne    KeyUp
  1072.  
  1073.         cmp.b    #$40,d0
  1074.         bhs    KeyDownSpecial
  1075.         and.w    #$003f,d0            ;$00..$3f
  1076.  
  1077.         cmp.b    #$0f,d0                ;Joystick-Emulation
  1078.         beq    KeyDownJoyFire
  1079.         cmp.b    #$1d,d0
  1080.         beq    KeyDownJoyDL
  1081.         cmp.b    #$1e,d0
  1082.         beq    KeyDownJoyDown
  1083.         cmp.b    #$1f,d0
  1084.         beq    KeyDownJoyDR
  1085.         cmp.b    #$2d,d0
  1086.         beq    KeyDownJoyLeft
  1087.         cmp.b    #$2e,d0
  1088.         beq    KeyDownJoyFire
  1089.         cmp.b    #$2f,d0
  1090.         beq    KeyDownJoyRight
  1091.         cmp.b    #$3d,d0
  1092.         beq    KeyDownJoyUL
  1093.         cmp.b    #$3e,d0
  1094.         beq    KeyDownJoyUp
  1095.         cmp.b    #$3f,d0
  1096.         beq    KeyDownJoyUR
  1097.  
  1098.         movem.w    KeyTable(pc,d0.w*4),d0/d1
  1099.         bclr    d1,(a0,d0.w)
  1100.         bclr    d0,(a1,d1.w)
  1101.         rts
  1102.  
  1103. KeyUp        cmp.b    #$40,d0
  1104.         bhs    KeyUpSpecial
  1105.         and.w    #$003f,d0            ;$00..$3f
  1106.  
  1107.         cmp.b    #$0f,d0                ;Joystick-Emulation
  1108.         beq    KeyUpJoyFire
  1109.         cmp.b    #$1d,d0
  1110.         beq    KeyUpJoyDL
  1111.         cmp.b    #$1e,d0
  1112.         beq    KeyUpJoyDown
  1113.         cmp.b    #$1f,d0
  1114.         beq    KeyUpJoyDR
  1115.         cmp.b    #$2d,d0
  1116.         beq    KeyUpJoyLeft
  1117.         cmp.b    #$2e,d0
  1118.         beq    KeyUpJoyFire
  1119.         cmp.b    #$2f,d0
  1120.         beq    KeyUpJoyRight
  1121.         cmp.b    #$3d,d0
  1122.         beq    KeyUpJoyUL
  1123.         cmp.b    #$3e,d0
  1124.         beq    KeyUpJoyUp
  1125.         cmp.b    #$3f,d0
  1126.         beq    KeyUpJoyUR
  1127.  
  1128.         movem.w    KeyTable(pc,d0.w*4),d0/d1
  1129.         bset    d1,(a0,d0.w)
  1130.         bset    d0,(a1,d1.w)
  1131. KeyNOP        rts
  1132.  
  1133. KeyDownSpecial    sub.b    #$40,d0
  1134.         cmp.b    #$20,d0
  1135.         bhs    KeyDownMod
  1136.         and.w    #$1f,d0                ;$40..$5f
  1137.         jmp    ([KeyDownSpecTab,pc,d0.w*4])
  1138.  
  1139. KeyDownMod    sub.b    #$20,d0
  1140.         cmp.b    #$08,d0
  1141.         bhs    KeyNOP
  1142.         and.w    #$07,d0                ;$60..$67
  1143.         cmp.w    #$07,d0                ;Amiga rechts ignorieren
  1144.         beq    1$
  1145.         movem.w    KeyModTable(pc,d0.w*4),d0/d1
  1146.         bclr    d1,(a0,d0.w)
  1147.         bclr    d0,(a1,d1.w)
  1148. 1$        rts
  1149.  
  1150. KeyUpSpecial    sub.b    #$40,d0
  1151.         cmp.b    #$20,d0
  1152.         bhs    KeyUpMod
  1153.         and.w    #$1f,d0                ;$40..$5f
  1154.         jmp    ([KeyUpSpecTab,pc,d0.w*4])
  1155.  
  1156. KeyUpMod    sub.b    #$20,d0
  1157.         cmp.b    #$08,d0
  1158.         bhs    KeyNOP
  1159.         and.w    #$07,d0                ;$60..$67
  1160.         cmp.w    #$07,d0                ;Amiga rechts ignorieren
  1161.         beq    1$
  1162.         movem.w    KeyModTable(pc,d0.w*4),d0/d1
  1163.         bset    d1,(a0,d0.w)
  1164.         bset    d0,(a1,d1.w)
  1165. 1$        rts
  1166.  
  1167. KeySpaceD    KeyDown    4,7
  1168.         rts
  1169. KeySpaceU    KeyUp    4,7
  1170.         rts
  1171. KeyBackD    KeyDown    0,0
  1172.         rts
  1173. KeyBackU    KeyUp    0,0
  1174.         rts
  1175. KeyTabD        KeyDown    7,7
  1176.         tst.b    NMIState    ;NMI schon ausgelöst?
  1177.         bne    1$
  1178.         st.b    IntIsNMI    ;Nein, NMI auslösen
  1179. 1$        rts
  1180. KeyTabU        KeyUp    7,7
  1181.         rts
  1182. KeyEnterD
  1183. KeyReturnD    KeyDown    1,0
  1184.         rts
  1185. KeyEnterU
  1186. KeyReturnU    KeyUp    1,0
  1187.         rts
  1188. KeyEscD        KeyDown    7,7
  1189.         rts
  1190. KeyEscU        KeyUp    7,7
  1191.         rts
  1192. KeyDeleteD    KeyDown    3,6
  1193.         rts
  1194. KeyDeleteU    KeyUp    3,6
  1195.         rts
  1196. KeyUpD        KeyDown    4,6
  1197.         KeyDown    7,0
  1198.         rts
  1199. KeyUpU        KeyUp    4,6
  1200.         KeyUp    7,0
  1201.         rts
  1202. KeyDownD    KeyDown    7,0
  1203.         rts
  1204. KeyDownU    KeyUp    7,0
  1205.         rts
  1206. KeyRightD    KeyDown    2,0
  1207.         rts
  1208. KeyRightU    KeyUp    2,0
  1209.         rts
  1210. KeyLeftD    KeyDown    4,6
  1211.         KeyDown    2,0
  1212.         rts
  1213. KeyLeftU    KeyUp    4,6
  1214.         KeyUp    2,0
  1215.         rts
  1216. KeyF1D        KeyDown    4,0
  1217.         rts
  1218. KeyF1U        KeyUp    4,0
  1219.         rts
  1220. KeyF3D        KeyDown    5,0
  1221.         rts
  1222. KeyF3U        KeyUp    5,0
  1223.         rts
  1224. KeyF5D        KeyDown    6,0
  1225.         rts
  1226. KeyF5U        KeyUp    6,0
  1227.         rts
  1228. KeyF7D        KeyDown    3,0
  1229.         rts
  1230. KeyF7U        KeyUp    3,0
  1231.         rts
  1232. KeyF2D        KeyDown    4,6
  1233.         KeyDown    4,0
  1234.         rts
  1235. KeyF2U        KeyUp    4,6
  1236.         KeyUp    4,0
  1237.         rts
  1238. KeyF4D        KeyDown    4,6
  1239.         KeyDOwn    5,0
  1240.         rts
  1241. KeyF4U        KeyUp    4,6
  1242.         KeyUp    5,0
  1243.         rts
  1244. KeyF6D        KeyDown    4,6
  1245.         KeyDown    6,0
  1246.         rts
  1247. KeyF6U        KeyUp    4,6
  1248.         KeyUp    6,0
  1249.         rts
  1250. KeyF8D        KeyDown    4,6
  1251.         KeyDown    3,0
  1252.         rts
  1253. KeyF8U        KeyUp    4,6
  1254.         KeyUp    3,0
  1255.         rts
  1256. KeyF9D        tst.b    NMIState    ;NMI schon ausgelöst?
  1257.         bne    1$
  1258.         st.b    IntIsNMI    ;Nein, NMI auslösen
  1259. 1$        rts
  1260. KeyNKAsterD    tst.w    KeyboardYZ
  1261.         bne    1$
  1262.         KeyDown    1,6    ;*
  1263.         rts
  1264. 1$        KeyDown    5,6    ;=
  1265.         rts
  1266. KeyNKAsterU    tst.w    KeyboardYZ
  1267.         bne    1$
  1268.         KeyUp    1,6
  1269.         rts
  1270. 1$        KeyUp    5,6
  1271.         rts
  1272. KeyNKSlashD    tst.w    KeyboardYZ
  1273.         bne    1$
  1274.         KeyDown    7,6    ;/
  1275.         rts
  1276. 1$        KeyDown    6,6    ;^
  1277.         rts
  1278. KeyNKSlashU    tst.w    KeyboardYZ
  1279.         bne    1$
  1280.         KeyUp    7,6
  1281.         rts
  1282. 1$        KeyUp    6,6
  1283.         rts
  1284. KeyNKLeftParD    KeyDown    4,6    ;[
  1285.         KeyDown    5,5
  1286.         rts
  1287. KeyNKLeftParU    KeyUp    4,6
  1288.         KeyUp    5,5
  1289.         rts
  1290. KeyNKRightParD    KeyDown    4,6    ;]
  1291.         KeyDown    2,6
  1292.         rts
  1293. KeyNKRightParU    KeyUp    4,6
  1294.         KeyUp    2,6
  1295.         rts
  1296.  
  1297. ; Joystick-Emulation
  1298. KeyDownJoyUp    bclr    #0,Joystick2Key
  1299.         rts
  1300. KeyDownJoyDown    bclr    #1,Joystick2Key
  1301.         rts
  1302. KeyDownJoyLeft    bclr    #2,Joystick2Key
  1303.         rts
  1304. KeyDownJoyRight    bclr    #3,Joystick2Key
  1305.         rts
  1306. KeyDownJoyUL    bclr    #0,Joystick2Key
  1307.         bclr    #2,Joystick2Key
  1308.         rts
  1309. KeyDownJoyUR    bclr    #0,Joystick2Key
  1310.         bclr    #3,Joystick2Key
  1311.         rts
  1312. KeyDownJoyDL    bclr    #1,Joystick2Key
  1313.         bclr    #2,Joystick2Key
  1314.         rts
  1315. KeyDownJoyDR    bclr    #1,Joystick2Key
  1316.         bclr    #3,Joystick2Key
  1317.         rts
  1318. KeyDownJoyFire    bclr    #4,Joystick2Key
  1319.         rts
  1320.  
  1321. KeyUpJoyUp    bset    #0,Joystick2Key
  1322.         rts
  1323. KeyUpJoyDown    bset    #1,Joystick2Key
  1324.         rts
  1325. KeyUpJoyLeft    bset    #2,Joystick2Key
  1326.         rts
  1327. KeyUpJoyRight    bset    #3,Joystick2Key
  1328.         rts
  1329. KeyUpJoyUL    bset    #0,Joystick2Key
  1330.         bset    #2,Joystick2Key
  1331.         rts
  1332. KeyUpJoyUR    bset    #0,Joystick2Key
  1333.         bset    #3,Joystick2Key
  1334.         rts
  1335. KeyUpJoyDL    bset    #1,Joystick2Key
  1336.         bset    #2,Joystick2Key
  1337.         rts
  1338. KeyUpJoyDR    bset    #1,Joystick2Key
  1339.         bset    #3,Joystick2Key
  1340.         rts
  1341. KeyUpJoyFire    bset    #4,Joystick2Key
  1342.         rts
  1343.  
  1344.  
  1345. **
  1346. ** Datenbereich
  1347. **
  1348.  
  1349.         CNOP    0,4
  1350. Registers1    ds.b    32    ;CIA-A-Register
  1351. Registers2    ds.b    32    ;CIA-B-Register
  1352.  
  1353. CIACycles    dc.w    0    ;Anzahl Phi2-Zyklen pro Rasterzeile (für Timer)
  1354. Joystick1On    dc.w    0    ;Joystick an Port 1 wird abgefragt
  1355. Joystick2On    dc.w    0    ;Joystick an Port 2 wird abgefragt
  1356.         XDEF    _JoystickSwap
  1357. _JoystickSwap
  1358. JoystickSwap    dc.w    0    ;Joysticks vertauschen
  1359. KeyboardYZ    dc.w    0    ;Amerikanische Tastaturbelegung
  1360.  
  1361. Joystick1    dc.b    0    ;Joystick 1 AND-Wert
  1362. Joystick2    dc.b    0    ;Joystick 2 AND-Wert
  1363. Joystick2Key    dc.b    0    ;Joystick 2 AND-Wert für Emulation über Zehnerblock
  1364.  
  1365. ; Tastaturübersetzungstabelle:
  1366. ; Für jeden Amiga-RawKey Spalte und Zeile in der KeyMatrix
  1367.         CNOP    0,4
  1368. KeyTable    dc.w    7,1    ;` -> <-
  1369.         dc.w    7,0    ;1
  1370.         dc.w    7,3    ;2
  1371.         dc.w    1,0    ;3
  1372.         dc.w    1,3    ;4
  1373.         dc.w    2,0    ;5
  1374.         dc.w    2,3    ;6
  1375.         dc.w    3,0    ;7
  1376.         dc.w    3,3    ;8
  1377.         dc.w    4,0    ;9
  1378.         dc.w    4,3    ;0
  1379.         dc.w    5,0    ;ß -> +
  1380.         dc.w    5,3    ;´ -> -
  1381.         dc.w    6,0    ;\ -> £
  1382.         dc.w    0,0
  1383.         dc.w    4,3    ;NP 0
  1384.  
  1385.         dc.w    7,6    ;Q
  1386.         dc.w    1,1    ;W
  1387.         dc.w    1,6    ;E
  1388.         dc.w    2,1    ;R
  1389.         dc.w    2,6    ;T
  1390. KeyPatch1    dc.w    1,4    ;Y -> Z
  1391.         dc.w    3,6    ;U
  1392.         dc.w    4,1    ;I
  1393.         dc.w    4,6    ;O
  1394.         dc.w    5,1    ;P
  1395.         dc.w    5,6    ;ü -> @
  1396.         dc.w    6,1    ;+ -> *
  1397.         dc.w    0,0
  1398.         dc.w    7,0    ;NP 1
  1399.         dc.w    7,3    ;NP 2
  1400.         dc.w    1,0    ;NP 3
  1401.  
  1402.         dc.w    1,2    ;A
  1403.         dc.w    1,5    ;S
  1404.         dc.w    2,2    ;D
  1405.         dc.w    2,5    ;F
  1406.         dc.w    3,2    ;G
  1407.         dc.w    3,5    ;H
  1408.         dc.w    4,2    ;J
  1409.         dc.w    4,5    ;K
  1410.         dc.w    5,2    ;L
  1411.         dc.w    5,5    ;ö -> :
  1412.         dc.w    6,2    ;ä -> ;
  1413.         dc.w    6,5    ;# -> =
  1414.         dc.w    0,0
  1415.         dc.w    1,3    ;NP 4
  1416.         dc.w    2,0    ;NP 5
  1417.         dc.w    2,3    ;NP 6
  1418.  
  1419.         dc.w    6,6    ;< -> ^
  1420. KeyPatch2    dc.w    3,1    ;Z -> Y
  1421.         dc.w    2,7    ;X
  1422.         dc.w    2,4    ;C
  1423.         dc.w    3,7    ;V
  1424.         dc.w    3,4    ;B
  1425.         dc.w    4,7    ;N
  1426.         dc.w    4,4    ;M
  1427.         dc.w    5,7    ;,
  1428.         dc.w    5,4    ;.
  1429.         dc.w    6,7    ;- -> /
  1430.         dc.w    0,0
  1431.         dc.w    5,4    ;NP .
  1432.         dc.w    3,0    ;NP 7
  1433.         dc.w    3,3    ;NP 8
  1434.         dc.w    4,0    ;NP 9
  1435.  
  1436. KeyDownSpecTab    dc.l    KeySpaceD
  1437.         dc.l    KeyBackD
  1438.         dc.l    KeyTabD
  1439.         dc.l    KeyEnterD
  1440.         dc.l    KeyReturnD
  1441.         dc.l    KeyEscD
  1442.         dc.l    KeyDeleteD
  1443.         dc.l    KeyNOP
  1444.  
  1445.         dc.l    KeyNOP
  1446.         dc.l    KeyNOP
  1447.         dc.l    KeyNOP
  1448.         dc.l    KeyNOP
  1449.         dc.l    KeyUpD
  1450.         dc.l    KeyDownD
  1451.         dc.l    KeyRightD
  1452.         dc.l    KeyLeftD
  1453.  
  1454.         dc.l    KeyF1D
  1455.         dc.l    KeyF2D
  1456.         dc.l    KeyF3D
  1457.         dc.l    KeyF4D
  1458.         dc.l    KeyF5D
  1459.         dc.l    KeyF6D
  1460.         dc.l    KeyF7D
  1461.         dc.l    KeyF8D
  1462.  
  1463.         dc.l    KeyF9D
  1464.         dc.l    KeyNOP
  1465.         dc.l    KeyNKLeftParD
  1466.         dc.l    KeyNKRightParD
  1467.         dc.l    KeyNKSlashD
  1468.         dc.l    KeyNKAsterD
  1469.         dc.l    KeyNOP
  1470.         dc.l    KeyNOP
  1471.  
  1472. KeyUpSpecTab    dc.l    KeySpaceU
  1473.         dc.l    KeyBackU
  1474.         dc.l    KeyTabU
  1475.         dc.l    KeyEnterU
  1476.         dc.l    KeyReturnU
  1477.         dc.l    KeyEscU
  1478.         dc.l    KeyDeleteU
  1479.         dc.l    KeyNOP
  1480.  
  1481.         dc.l    KeyNOP
  1482.         dc.l    KeyNOP
  1483.         dc.l    KeyNOP
  1484.         dc.l    KeyNOP
  1485.         dc.l    KeyUpU
  1486.         dc.l    KeyDownU
  1487.         dc.l    KeyRightU
  1488.         dc.l    KeyLeftU
  1489.  
  1490.         dc.l    KeyF1U
  1491.         dc.l    KeyF2U
  1492.         dc.l    KeyF3U
  1493.         dc.l    KeyF4U
  1494.         dc.l    KeyF5U
  1495.         dc.l    KeyF6U
  1496.         dc.l    KeyF7U
  1497.         dc.l    KeyF8U
  1498.  
  1499.         dc.l    KeyNOP
  1500.         dc.l    KeyNOP
  1501.         dc.l    KeyNKLeftParU
  1502.         dc.l    KeyNKRightParU
  1503.         dc.l    KeyNKSlashU
  1504.         dc.l    KeyNKAsterU
  1505.         dc.l    KeyNOP
  1506.         dc.l    KeyNOP
  1507.  
  1508. KeyModTable    dc.w    1,7        ;Shift left
  1509.         dc.w    6,4        ;Shift right
  1510.         dc.w    1,7        ;Caps lock -> Shift left
  1511.         dc.w    7,2        ;Control
  1512.         dc.w    7,5        ;Alt left -> C=
  1513.         dc.w    7,5        ;Alt right -> C=
  1514.         dc.w    7,5        ;Amiga left -> C=
  1515.         dc.w    0,0        ;Amiga right
  1516.  
  1517. ; Bit  7   6   5   4   3   2   1   0
  1518. ; 0   CUD  F5  F3  F1  F7 CLR RET DEL
  1519. ; 1   SHL  E   S   Z   4   A   W   3
  1520. ; 2    X   T   F   C   6   D   R   5
  1521. ; 3    V   U   H   B   8   G   Y   7
  1522. ; 4    N   O   K   M   0   J   I   9
  1523. ; 5    ,   @   :   .   -   L   P   +
  1524. ; 6    /   ^   =  SHR HOM  ;   *   £
  1525. ; 7   R/S  Q   C= SPC  2  CTL  <-  1
  1526.  
  1527. KeyMatrix    ds.b    8    ;C64-Tastaturmatrix pro Taste ein Bit
  1528.                 ;0: Taste gedrückt
  1529. InvKeyMatrix    ds.b    8    ;Gespiegelte Tastaturmatrix
  1530.  
  1531.         END
  1532.